import java.util.*;

public class Solution987 {
    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode() {}
        TreeNode(int val) { this.val = val; }
        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    class NodeInfo implements Comparable{
        int colNum;
        int rowNum;
        int nodeVal;
        public NodeInfo() {
        }
        public NodeInfo(int colNum, int rowNum, int nodeVal) {
            this.colNum = colNum;
            this.rowNum = rowNum;
            this.nodeVal = nodeVal;
        }
        @Override
        public int compareTo(Object o) {
            NodeInfo no = ((NodeInfo)o);
            int sub = this.rowNum - no.rowNum;
            if(sub != 0){
                return sub;
            }
            return this.nodeVal - no.nodeVal;
        }
    }

    private void travel(Map<Integer, List<NodeInfo>> counter, TreeNode tmpNode, int colNum, int rowNum){
        if(tmpNode == null){
            return;
        }
        List<NodeInfo> tmpList = counter.getOrDefault(colNum, new LinkedList<>());
        tmpList.add(new NodeInfo(colNum, rowNum, tmpNode.val));
        counter.put(colNum, tmpList);
        travel(counter, tmpNode.left, colNum-1, rowNum+1);
        travel(counter, tmpNode.right, colNum+1, rowNum+1);
    }

    public List<List<Integer>> verticalTraversal(TreeNode root) {
        Map<Integer, List<NodeInfo>> counter = new TreeMap<>();
        travel(counter, root, 0, 0);
        List<List<Integer>> res = new LinkedList<>();
        for (Map.Entry et:counter.entrySet()) {
            List<Integer> tmpRes = new LinkedList();
            List<NodeInfo> list = (List)et.getValue();
            Collections.sort(list);
            for (NodeInfo no:list) {
                tmpRes.add(no.nodeVal);
            }
            res.add(tmpRes);
        }
        return res;
    }
}
